package com.ztfgroup.supervise.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hszsd.weixin.api.SmsAPI;
import com.hszsd.weixin.in.TextcardIn;
import com.hszsd.weixin.in.TextcardMessageIn;
import com.hszsd.weixin.out.GetUserInfoOut;
import com.ztfgroup.supervise.entity.*;
import com.ztfgroup.supervise.entity.vo.FeedbackVO;
import com.ztfgroup.supervise.entity.vo.UserTaskVO;
import com.ztfgroup.supervise.mapper.FeedbackMapper;
import com.ztfgroup.supervise.mapper.MessageMapper;
import com.ztfgroup.supervise.service.IFeedbackService;
import com.ztfgroup.supervise.service.ITaskService;
import com.ztfgroup.supervise.service.IUserService;
import com.ztfgroup.supervise.service.IUserTaskService;
import com.ztfgroup.supervise.util.Constants;
import com.ztfgroup.supervise.wxparam.AccessTokenApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 任务跟踪表 服务实现类
 * </p>
 *
 * @author hejr
 * @since 2019-02-25
 */
@Service
@Slf4j
public class FeedbackServiceImpl extends ServiceImpl<FeedbackMapper, Feedback> implements IFeedbackService {

    @Value("${supervise.agentId}")
    private Integer agentId;

    @Value("${supervise.corpId}")
    private String corpId;

    @Value("${supervise.corpSecret}")
    private String corpSecret;


    @Value("${supervise.domainHost}")
    private String domainHost;

    @Autowired
    private AccessTokenApi accessTokenApi;

    @Autowired
    private ITaskService taskService;

    @Autowired
    private IUserTaskService userTaskService;

    @Autowired
    private IUserService userService;

    @Autowired
    private MessageMapper messageMapper;


    @Override
    public List<FeedbackVO> findFeedbackByTaskId(String taskId) {
        return baseMapper.findFeedbackByTaskId(taskId);
    }


    @Override
    public Integer addFeeback(String roleId, String userId, String taskId, String taskStatus, String feedbackContent) {
        Integer result = -1;
        Feedback feedback = new Feedback();
        feedback.setFeedbackId(Constants.FEEDBACK_ID_PREX);
        feedback.setUserId(userId);
        feedback.setTaskId(taskId);
        feedback.setTaskStatus(Constants.FEEDBACK_STATUS_MAP.get(taskStatus));
        feedback.setFeedbackContent(StringEscapeUtils.escapeHtml4(feedbackContent));
        feedback.setFeedbackTime(Constants.DATE_FORMAT_SPECIAL_DAY.format(new Date()));
        try {
            result = baseMapper.addFeeback(feedback);
            //异步推送消息
            if (result > 0) {
                if (StringUtils.isNotEmpty(taskStatus)) {
                    //项目责任人更新任务状态
                    if (roleId.equals(Constants.PERSON_LIABLE_ROLE)) {
                        updateTaskStatus(taskId, taskStatus, null);
                    }
                    //任务状态为已完成，更新完成时间
                    if (taskStatus.equals(Constants.TASK_FINISH_STATUS)) {
                        updateTaskStatus(taskId, taskStatus, Constants.DATE_FORMAT_FINISH_TIME.format(new Date()));
                    }
                }
                String userName = userService.selectById(userId).getUserName();
                Integer role = userTaskService.selectOne(new QueryWrapper<UserTask>().eq("USER_ID", userId).eq("TASK_ID", taskId)).getRole();
                Thread t = new Thread(new FeedbackClusterThread(taskId, userId, userName, role, feedbackContent));
                t.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 反馈信息微信推送内部类
     */
    class FeedbackClusterThread implements Runnable {

        String taskId;
        String userId;
        String userName;
        Integer role;
        String feedbackContent;

        public FeedbackClusterThread() {
        }

        public FeedbackClusterThread(String taskId, String userId, String userName, Integer role, String feedbackContent) {
            this.taskId = taskId;
            this.userId = userId;
            this.userName = userName;
            this.role = role;
            this.feedbackContent = feedbackContent;
        }

        @Override
        public void run() {
            log.info("begin feedback push....");
            try {
                sendWechatMessage(userId, taskId, userName, role, feedbackContent);
            } catch (Exception e) {
                log.error("eedback push is abnormal...");
            }
            log.info("feedback push is over...");
        }
    }

    private void updateTaskStatus(String taskId, String taskStatus, String finishTime) {
        Task task = new Task();
        task.setTaskId(taskId);
        if (StringUtils.isNotEmpty(taskStatus)) {
            task.setStatus(taskStatus);
        }
        if (StringUtils.isNotEmpty(finishTime)) {
            task.setFinishTime(finishTime);
        }
        taskService.updateById(task);
    }

    private void sendWechatMessage(String userId, String taskId, String userName, Integer role, String feedbackContent) {
        String taskName = "";
        String wxUserIds = "";
        String deptName = "";
        String roleName = "";
        String categoryName = "";
        String suggest = "";
        try {
            StringBuffer wxUserId = new StringBuffer("");
            List<UserTaskVO> userTaskVOList = userTaskService.findUserInfoByTaskId(userId, taskId);
            if (userTaskVOList != null && !userTaskVOList.isEmpty()) {
                for (UserTaskVO vo : userTaskVOList) {
                    List<User> userList = vo.getUserList();
                    for (User user : userList) {
                        wxUserId.append(user.getWxUserId()).append(Constants.LINE_SEPARATE_CHAR);
                    }
                    if (StringUtils.isEmpty(taskName)) {
                        taskName = vo.getTask().getTaskName();
                    }
                    if (StringUtils.isEmpty(deptName)) {
                        deptName = vo.getDept().getDeptName();
                    }
                    if (StringUtils.isEmpty(categoryName)) {
                        categoryName = vo.getCategory().getCategoryName();
                    }
                }
                wxUserIds = wxUserId.subSequence(0, wxUserId.length() - 1).toString();
                log.info("待推送用户ID：[" + wxUserIds + "]");
                //当前时间
                String dateTime = Constants.DATE_FORMAT_SEND_TIME.format(new Date());
                //推送内容
                String description = "";
                //角色是提出人，则推送消息格式变更
                if (role.equals(Constants.LEADER_ROLE_ID)) {
                    roleName = "董事长";
                    suggest = "指示";
                    description = Constants.WECHAT_MSG_TEMPLATE.replace("${dateTime}", dateTime)
                            .replace("${roleName}-${userName}", roleName)
                            .replace("${suggest}", suggest)
                            .replace("${feedbackContent}", truncateContent(feedbackContent))
                            .replace("${categoryName}", categoryName)
                            .replace("${deptName}", deptName)
                            .replace("${taskName}", taskName);
                } else {
                    roleName = Constants.ROLE_MAP.get(role);
                    suggest = Constants.ROLE_MSG_MAP.get(role);
                    description = Constants.WECHAT_MSG_TEMPLATE.replace("${dateTime}", dateTime)
                            .replace("${roleName}", roleName)
                            .replace("${userName}", userName)
                            .replace("${suggest}", suggest)
                            .replace("${feedbackContent}", truncateContent(feedbackContent))
                            .replace("${categoryName}", categoryName)
                            .replace("${deptName}", deptName)
                            .replace("${taskName}", taskName);
                }
                String accessToken = accessTokenApi.getAccessToken(corpId, corpSecret);
                TextcardMessageIn textcardMessageIn = new TextcardMessageIn();
                textcardMessageIn.setTouser(wxUserIds);
                textcardMessageIn.setAgentid(agentId);
                textcardMessageIn.setMsgtype("textcard");
                TextcardIn textcardIn = new TextcardIn();
                textcardIn.setBtntxt("点击查看详情");
                textcardIn.setTitle("消息提醒");
                textcardIn.setDescription(description);
                textcardIn.setUrl("http://" + domainHost + "/detail?taskId=" + taskId);
                textcardMessageIn.setTextcard(textcardIn);
                GetUserInfoOut in = SmsAPI.sendMessage(accessToken, textcardMessageIn);

                //往消息表中新增数据
                Message message = new Message();
                message.setId(Constants.MESSAGE_ID_PREX);
                message.setSendTime(Constants.DATE_FORMAT_SPECIAL_DAY.format(new Date()));
                message.setSender(userId);
                message.setReceiver(wxUserIds);
                message.setContent(description);
                message.setType("G");
                message.setStatus(String.valueOf(in.getErrcode()));
                Integer ret = messageMapper.addMessage(message);
                log.info("推送消息入库" + (ret > 0 ? "成功" : "失败"));
            } else {
                log.info("改项目没有可推送的微信用户，taskId：{}", taskId);
            }
        } catch (Exception e) {
            log.error("消推送失败，userId：{}，taksId：{}", userId, taskId);
            e.printStackTrace();
        }
    }

    /**
     * 截取字符串
     *
     * @param feedbackContent
     * @return
     */
    private static String truncateContent(String feedbackContent) {
        String cutContent = "";
        if (StringUtils.isNotEmpty(feedbackContent)) {
            cutContent = feedbackContent.length() > Constants.MAX_CONTENT_LENGTH ? feedbackContent.substring(0, Constants.MAX_CONTENT_LENGTH) + "..." : feedbackContent;
        }
        return cutContent;
    }
}
